'''
Created on 2010-4-8

@author: chengmeng
'''
import wx
import ogre.renderer.OGRE as ogre 

class TDo:
	def __init__(self,n):
		self.n = n
		self.p = n.getPosition()
		self.s = n.getScale()
		self.o = n.getOrientation()
		pass

	def build(self,edit):
		if self.p != self.n.getPosition()\
		or self.s != self.n.getScale()\
		or self.o != self.n.getOrientation():
			
			self.np = self.n.getPosition()
			self.ns = self.n.getScale()
			self.no = self.n.getOrientation()

			edit.addDo(self)
		pass

	def undo(self):
		self.n.setPosition(self.p)
		self.n.setScale(self.s)
		self.n.setOrientation(self.o)
		pass
	
	def redo(self):
		self.n.setPosition(self.np)
		self.n.setScale(self.ns)
		self.n.setOrientation(self.no)
		pass

class DDo:
	def __init__(self,n,edit,frame):
		self.n = n
		self.p = n.getParent()

		self.frame = frame

		edit.addDo(self)
		pass

	def undo(self):
		self.p.addChild(self.n)
		self.frame.plugins.updateScene()
		pass

	def redo(self):
		self.p.removeChild(self.n)
		self.frame.plugins.updateScene()
		pass

class Plugin:

	def __init__(self,frame):
		frame.plugins.OgreWindowPlugin.addMouseListener(self._MouseEventListener)
		frame.plugins.OgreWindowPlugin.addKeyDownListener(self._KeyDownEventListener)
		frame.plugins.OgreWindowPlugin.addKeyUpListener(self._KeyUpEventListener)
		self.sm = frame.plugins.OgreWindowPlugin.getSceneManager()
		self.selecter = frame.plugins.SceneSelectorPlugin
		self.frame = frame
		
		self.q = False
		self.w = False
		self.e = False
		
		self.a = False
		self.s = False
		self.d = False
		
		self.z = False
		self.x = False
		self.c = False
		self.v = False
		
		
		self.StartDragX, self.StartDragY = 0,0
		
		self._do = None
		pass

	def controlEnable(self,b):
		pass

	def controlDlg(self):
		pass

	def _MouseEventListener(self, event):
		if event.ControlDown() or event.AltDown() or event.ShiftDown():
			return
		
		f = 0.05
		sf = 0.1
		
		s = self.selecter.getCurrSelectNode()

		if event.Moving() and s:
			x,y = event.GetPosition() 
			dx = (x-self.StartDragX) * f
			dy = (y-self.StartDragY) * f
			self.StartDragX, self.StartDragY = x, y 

			if self.q :#q
				s.translate(ogre.Vector3(dx,0.0,0.0),s.TS_WORLD)
				event.Skip() 
				pass
			elif self.w :#w
				s.translate(ogre.Vector3(0.0,-dy,0.0),s.TS_WORLD)
				event.Skip() 
				pass
			elif self.e :#e
				s.translate(ogre.Vector3(0.0,0.0,dx),s.TS_WORLD)
				event.Skip() 
				pass
			
			elif self.a :#a
				s.yaw(ogre.Degree(dx*2.0)) 
				event.Skip() 
				pass
			elif self.s :#s
				s.pitch(ogre.Degree(dx*2.0)) 
				event.Skip() 
				pass
			elif self.d :#d
				s.roll(ogre.Degree(dx*2.0)) 
				event.Skip() 
				pass
			
			elif self.z :#z
				scale = s.getScale()
				s.setScale(scale.x + dx * sf,scale.y + dx * sf,scale.z + dx * sf) 
				event.Skip() 
				pass
			elif self.x :#x
				scale = s.getScale()
				s.setScale(scale.x + dx * sf,scale.y,scale.z) 
				event.Skip() 
				pass
			elif self.c :#c
				scale = s.getScale()
				s.setScale(scale.x,scale.y + dx * sf,scale.z) 
				event.Skip() 
			elif self.v :#v
				scale = s.getScale()
				s.setScale(scale.x,scale.y,scale.z + dx * sf) 
				event.Skip() 
				pass
		pass

	def _KeyDownEventListener(self,event): 
		
		if self._do != None or event.ControlDown() or event.AltDown() or event.ShiftDown():
			return

		kc = event.GetKeyCode()

		if kc ==  81:#q
			self.q = True
			event.Skip() 
			pass
		elif kc == 87 :#w
			self.w = True
			event.Skip() 
			pass
		elif kc == 69 :#e
			self.e = True
			event.Skip() 
			pass
		elif kc == 65 :#a
			self.a = True
			event.Skip() 
			pass
		elif kc == 83:#s
			self.s = True
			event.Skip() 
			pass
		elif kc == 68:#d
			self.d = True
			event.Skip() 
			pass
		elif kc == 90:#z
			self.z = True
			event.Skip() 
			pass
		elif kc == 88:#x
			self.x = True
			event.Skip() 
			pass
		elif kc == 67:#c
			self.c = True
			event.Skip() 
			pass
		elif kc == 86:#v
			self.v = True
			event.Skip() 
			pass

		if 	event.GetSkipped() :
			self.StartDragX, self.StartDragY = event.GetPosition()
			self._do = TDo(self.selecter.getCurrSelectNode())
			self._do.kc = kc
		pass

	def _KeyUpEventListener(self,event): 
		if event.ControlDown() or event.AltDown() or event.ShiftDown():
			return
		
		kc = event.GetKeyCode()
		
		if kc ==  81:#q
			self.q = False
			event.Skip() 
			pass
		elif kc == 87 :#w
			self.w = False
			event.Skip() 
			pass
		elif kc == 69 :#e
			self.e = False
			event.Skip() 
			pass
		elif kc == 65 :#a
			self.a = False
			event.Skip() 
			pass
		elif kc == 83:#s
			self.s = False
			event.Skip() 
			pass
		elif kc == 68:#d
			self.d = False
			event.Skip() 
			pass
		elif kc == 90:#z
			self.z = False
			event.Skip() 
			pass
		elif kc == 88:#x
			self.x = False
			event.Skip() 
			pass
		elif kc == 67:#c
			self.c = False
			event.Skip() 
		elif kc == 86:#v
			self.v = False
			event.Skip() 
			pass 

		elif kc == wx.WXK_DELETE:#delete
			s = self.selecter.getCurrSelectNode()
			if s != None :
				if s.getParent() != None :
					if self._msg_is_delete("SceneNode " + '<' + s.getName() + '>'):
						self.selecter.setCurrSelectNode(None)
						DDo(s,self.frame.plugins.EditPlugin,self.frame)
						s.getParent().removeChild(s)
		#				for mo in s.getAttachedObjectIterator():
		#					self.sm.destroyMovableObject(mo)
		#				self.sm.destroySceneNode(s)

						self.frame.plugins.updateScene()

			event.Skip() 
			pass
		
		if 	event.GetSkipped() and kc != wx.WXK_DELETE and self._do and self._do.kc == kc:
			self._do.build(self.frame.plugins.EditPlugin)
			del self._do.kc
			self._do = None

		pass


	def _msg_is_delete(self,s):

		dlg = wx.MessageDialog(self.frame.plugins.OgreWindowPlugin,
								'Are you sure to delete ' + s,
		                       	'A Message Box',
		                       	wx.YES_NO | wx.ICON_INFORMATION | wx.NO_DEFAULT
		                       	#wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION
		                       	)
		is_yes = dlg.ShowModal()
		dlg.Destroy()
		return is_yes == wx.ID_YES

	def IHelp(self):
		return """key q w e and move mouse to move the select node
key a s d and move mouse to scale the select node
key z x c v and move mouse to orientation the select node
key delete to delete the select node"""

##
def IInit(frame):
	return Plugin(frame)
